<html>
<head>
  <title>Evernote Export</title>
  <basefont face="微软雅黑" size="2" />
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  <meta name="exporter-version" content="YXBJ Windows/601748 (zh-CN, DDL); Windows/10.0.0 (Win64); EDAMVersion=V2;"/>
  <style>
    body, td {
      font-family: 微软雅黑;
      font-size: 10pt;
    }
  </style>
</head>
<body>
<a name="630"/>

<div>
<span><div><div><span style="font-size: 12pt;">函数在创建的时候会创建两个对象，一个是函数对象本身，另一个是作用域链对象</span></div><div><span style="font-size: 12pt;">函数在调用的时候会创建一个执行环境对象（活动对象）</span></div><div><br/></div><div><span style="font-size: 12pt; font-weight: bold;">闭包（ closure ）</span></div><div><br clear="none"/></div><div><span style="font-size: 12pt;">    问题：全局变量和局部变量各自有什么缺点？</span></div><div><span style="font-size: 12pt;">              全局变量：在函数体外定义的变量，每个函数都能使用修改，就会造成全局污染</span></div><div><span style="font-size: 12pt;">              局部变量：在函数体内定义的变量，只有当前函数能使用，但是不能在全局重复使用</span></div><div><br clear="none" style="font-size: 12pt;"/></div><div><br clear="none" style="font-size: 12pt;"/></div><div><br/></div><div><span style="font-size: 12pt;">既能重复使用，又不会污染全局？闭包！</span></div><div><br clear="none" style="font-size: 12pt;"/></div><div><span style="font-size: 12pt;">闭包有三步：</span></div><div><span style="font-size: 12pt;">   1、外层函数嵌套内层函数</span></div><div><span style="font-size: 12pt;">   2、内层函数使用外层函数的局部变量</span></div><div><span style="font-size: 12pt;">   3、把内层函数作为外层函数的返回值</span></div><div><br clear="none" style="font-size: 12pt;"/></div><div><span style="font-size: 12pt;">闭包可以在全局函数里面操作另一个作用域的局部变量</span></div><div><br clear="none" style="font-size: 12pt;"/></div><div><span style="font-size: 12pt;">什么时候使用闭包？</span></div><div><br clear="none" style="font-size: 12pt;"/></div><div><span style="font-size: 12pt;">  既能重复使用，又不会污染全局</span></div><div><br/></div><div><br/></div><div><span style="font-size: 12pt;">1、预解析</span></div><div><br clear="none"/></div><div><img src="00-笔记_files/1-预解析.png" type="image/png" data-filename="1-预解析.png"/></div><div><img src="00-笔记_files/2-调用时.png" type="image/png" data-filename="2-调用时.png"/></div><div><br clear="none"/></div><div><img src="00-笔记_files/3-调用后.png" type="image/png" data-filename="3-调用后.png"/></div><div><br clear="none"/></div><div><img src="00-笔记_files/4-fn调用时.png" type="image/png" data-filename="4-fn调用时.png"/></div><div><br clear="none"/></div><div><img src="00-笔记_files/5-fn调用后.png" type="image/png" data-filename="5-fn调用后.png"/></div><div><span style="font-size: 12pt;">    </span></div><div><span style="font-size: 12pt;"> </span></div><div><span style="font-size: 12pt;"><br/></span></div><div><span style="font-size: 12pt;"><br/></span></div><div><span style="font-size: 12pt;">OOP三大特点：封装、继承、多态</span></div><div><span style="font-size: 12pt;"><br/></span></div><div><span style="font-size: 14pt; font-weight: bold;">继承</span></div><div><span style="font-size: 14pt; font-weight: bold;">多态：重写、重载</span></div><div><br clear="none"/></div><div><span style="font-size: 12pt;">子类共享父类的属性和方法,js的继承都是基于原型实现的</span></div><div><br/></div><div><span style="font-size: 12pt;">//定义一个动物类</span></div><div><br clear="none"/></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">function Animal (name) {</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">    // 属性</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">    this.name = name;</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">    // 实例方法</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">    this.say= function(){</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">      <span style="font-size: 12pt; font-family: Monaco; color: #333333;">console.log</span><span style="font-family: Monaco; font-size: 12pt; color: #333333;">(&quot;My name is &quot;+this.name);</span></span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">    }</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">}</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">// 原型方法</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">Animal.prototype.eat = function(food) {</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">    console.log(this.name + '正在吃：' + food);</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">};</span></div></div><div><br clear="none"/></div><div><br clear="none"/></div><div><br clear="none"/></div><div><br clear="none"/></div><ol><li><div><span style="font-size: 12pt;"><span style="font-size: 12pt; font-weight: bold;">原型链继承：子类的原型指向父类的实例</span></span></div></li></ol><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">function Cat(){</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">}</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">Cat.prototype = new Animal();</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">Cat.prototype.name = 'cat';</span></div><div><br clear="none" style="font-family: Monaco; font-size: 9pt; color: #333333;"/></div><div><br clear="none" style="font-family: Monaco; font-size: 9pt; color: #333333;"/></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">var cat = new Cat();</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">console.log(cat.name);</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">cat.say();</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">cat.eat('fish');</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">console.log(cat instanceof Animal); //true</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">console.log(cat instanceof Cat); //true</span></div></div><div><span style="font-size: 12pt;">          </span></div><div><div style="margin-top: 1em;margin-bottom: 1em;-en-paragraph:true;"><span style="font-size: 12pt;">特点：</span></div><ol><li><div><span style="font-size: 12pt;">非常纯粹的继承关系，实例是子类的实例，也是父类的实例</span></div></li></ol><div><span style="font-size: 12pt;">      2.父类新增原型方法/原型属性，子类都能访问到</span></div><div><span style="font-size: 12pt;">      3.简单，易于实现</span></div><div style="margin-top: 1em;margin-bottom: 1em;-en-paragraph:true;"><span style="font-size: 12pt;">缺点：</span></div><ol><li><div><span style="font-size: 12pt;">要想为子类新增属性和方法，必须要在new Animal()这样的语句之后执行，不能放到构造器中</span></div></li><li><div><span style="font-size: 12pt;">无法实现多继承</span></div></li><li><div><span style="font-size: 12pt;">来自原型对象的引用属性是所有实例共享的</span></div></li><li><div><span style="font-size: 12pt;">创建子类实例时，无法向构造函数传参</span></div></li></ol></div><div><br clear="none"/></div><div><br clear="none"/></div><ol start="2"><li><div><span style="font-size: 12pt;"><span style="font-size: 12pt; font-weight: bold;">构造继承（call、apply继承）</span></span></div></li></ol><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">function Cat(name){</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">    Animal.call(this,name);</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">}</span></div><div><br clear="none" style="font-family: Monaco; font-size: 9pt; color: #333333;"/></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">var cat = new Cat(&quot;Tom&quot;);</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">console.log(cat.name);</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">cat<span style="font-size: 12pt; font-family: Monaco; color: #333333;">.say();</span></span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">console.log(cat instanceof Animal); // false</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">console.log(cat instanceof Cat); // true</span></div></div><div><br clear="none"/></div><div><div style="margin-top: 1em;margin-bottom: 1em;-en-paragraph:true;"><span style="font-size: 12pt;">特点：</span></div><ol><li><div><span style="font-size: 12pt;">解决了1中，子类实例共享父类引用属性的问题</span></div></li><li><div><span style="font-size: 12pt;">创建子类实例时，可以向父类传递参数</span></div></li><li><div><span style="font-size: 12pt;">可以实现多继承（call多个父类对象）</span></div></li></ol><div style="margin-top: 1em;margin-bottom: 1em;-en-paragraph:true;"><span style="font-size: 12pt;">缺点：</span></div><ol><li><div><span style="font-size: 12pt;">实例并不是父类的实例，只是子类的实例</span></div></li><li><div><span style="font-size: 12pt;">只能继承父类的实例属性和方法，不能继承原型属性/方法</span></div></li><li><div><span style="font-size: 12pt;">无法实现函数复用，每个子类都有父类实例函数的副本，影响性能</span></div></li></ol><div><br clear="none"/></div></div><div><br clear="none"/></div><ol><li><div><span style="font-size: 12pt;"><span style="font-size: 12pt; font-weight: bold;">拷贝继承</span></span></div></li></ol><div><br clear="none"/></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">function Cat(name){</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">    var animal = new Animal(<span style="font-size: 12pt; font-family: Monaco; color: #333333;">name</span>);</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">    for(var key in animal){</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">        Cat.prototype[<span style="font-size: 12pt; font-family: Monaco; color: #333333;">key</span>] = animal[<span style="font-size: 12pt; font-family: Monaco; color: #333333;">key</span>];</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">    }</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">}</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">// Test Code</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">var cat = new Cat(&quot;Tom&quot;);</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">console.log(cat.name);</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">cat<span style="font-size: 12pt; font-family: Monaco; color: #333333;">.say();</span></span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">console.log(cat instanceof Animal); // false</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">console.log(cat instanceof Cat); // true</span></div></div><div><br clear="none"/></div><div><div style="margin-top: 1em;margin-bottom: 1em;-en-paragraph:true;"><span style="font-size: 12pt;">特点：</span></div><ol><li><div><span style="font-size: 12pt;">支持多继承</span></div></li></ol><div style="margin-top: 1em;margin-bottom: 1em;-en-paragraph:true;"><span style="font-size: 12pt;">缺点：</span></div><ol><li><div><span style="font-size: 12pt;">效率较低，内存占用高（因为要拷贝父类的属性）</span></div></li><li><div><span style="font-size: 12pt;">无法获取父类不可枚举的方法（不可枚举方法，不能使用for in 访问到）  </span></div></li></ol><div><br clear="none"/></div></div><div><br clear="none"/></div><ol start="4"><li><div><span style="font-size: 12pt;"><span style="font-size: 12pt; font-weight: bold;">组合继承（原型链和构造继承的组合）</span></span></div></li></ol><div><br clear="none"/></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">function Cat(name){</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">    Animal.call(this,name);</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">}</span></div><div><br clear="none"/></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">Cat.prototype = new Animal();</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">Cat.prototype.constructor = Cat;</span></div><div><br clear="none" style="font-family: Monaco; font-size: 9pt; color: #333333;"/></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">// Test Code</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">var cat = new Cat();</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">console.log(cat.name);</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">cat<span style="font-size: 12pt; font-family: Monaco; color: #333333;">.say();</span></span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">console.log(cat instanceof Animal); // true</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">console.log(cat instanceof Cat); // true</span></div></div><div><br clear="none"/></div><div><div style="margin-top: 1em;margin-bottom: 1em;-en-paragraph:true;"><span style="font-size: 12pt;">特点：</span></div><ol><li><div><span style="font-size: 12pt;">弥补了方式2的缺陷，可以继承实例属性/方法，也可以继承原型属性/方法</span></div></li></ol><ol><li><div><span style="font-size: 12pt;">既是子类的实例，也是父类的实例</span></div></li><li><div><span style="font-size: 12pt;">不存在引用属性共享问题</span></div></li><li><div><span style="font-size: 12pt;">可传参</span></div></li><li><div><span style="font-size: 12pt;">函数可复用</span></div></li></ol><div style="margin-top: 1em;margin-bottom: 1em;-en-paragraph:true;"><span style="font-size: 12pt;">缺点：</span></div><div><span style="font-size: 12pt;">    调用了两次父类构造函数，生成了两份实例（子类实例将子类原型上的那份屏蔽了）</span></div><div><br clear="none"/></div><div><br clear="none"/></div><div><span style="font-size: 12pt;">     </span><span style="font-size: 12pt; font-weight: bold;">5.寄生组合继承</span></div><div><br clear="none"/></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">function Cat(name){</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">    Animal.call(this);</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">    this.name = name;</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">}</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">(function(){</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">    // 创建一个没有实例方法的类</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">    var Super = function(){};</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">    Super.prototype = Animal.prototype;</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">    //将实例作为子类的原型</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">    Cat.prototype = new Super();</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">})();</span></div><div><br clear="none" style="font-family: Monaco; font-size: 9pt; color: #333333;"/></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">// Test Code</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">var cat = new Cat();</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">console.log(cat.name);</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">cat<span style="font-size: 12pt; font-family: Monaco; color: #333333;">.say();</span></span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">console.log(cat instanceof Animal); // true</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">console.log(cat instanceof Cat); //true</span></div></div><div><br clear="none"/></div><div style="margin-top: 1em;margin-bottom: 1em;-en-paragraph:true;"><span style="font-size: 12pt;">特点：堪称完美</span></div><div style="margin-top: 1em;margin-bottom: 1em;-en-paragraph:true;"><span style="font-size: 12pt;">缺点：实现较为复杂</span></div><div><br clear="none"/></div><div><br clear="none"/></div></div><div><br clear="none"/></div><div><span style="font-size: 12pt;">     </span> <span style="font-size: 12pt; font-weight: bold;">6. ES6继承（语法糖）</span></div><div><br clear="none"/></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><span style="font-family: Monaco; color: #333333;"><span style="font-size: 12pt;">class Animal{</span></span></div><div><span style="font-family: Monaco; color: #333333;"><span style="font-size: 12pt;">    constructor(name){</span></span></div><div><span style="font-family: Monaco; color: #333333;"><span style="font-size: 12pt;">        this.name = name;</span></span></div><div><span style="font-size: 12pt; font-family: Monaco;">    }</span></div><div><span style="font-family: Monaco; color: #333333;"><span style="font-size: 12pt;">    say(){</span></span></div><div><span style="font-family: Monaco; color: #333333;"><span style="font-size: 12pt;">        alert(&quot;My name is &quot;+this.name);</span></span></div><div><span style="font-family: Monaco; color: #333333;"><span style="font-size: 12pt;">    }</span></span></div><div><span style="font-family: Monaco; color: #333333;"><span style="font-size: 12pt;">    eat(food){</span></span></div><div><span style="font-family: Monaco; color: #333333;"><span style="font-size: 12pt;">        alert(this.name+&quot; is eating &quot;+food);</span></span></div><div><span style="font-family: Monaco; color: #333333;"><span style="font-size: 12pt;">    }</span></span></div><div><span style="font-family: Monaco; color: #333333;"><span style="font-size: 12pt;">}</span></span></div><div><span style="font-family: Monaco; color: #333333;"><span style="font-size: 12pt;">class Cat extends Animal{</span></span></div><div><span style="font-family: Monaco; color: #333333;"><span style="font-size: 12pt;">    constructor(name){</span></span></div><div><span style="font-family: Monaco; color: #333333;"><span style="font-size: 12pt;">        super(name);</span></span></div><div><span style="font-family: Monaco; color: #333333;"><span style="font-size: 12pt;">    }</span></span></div><div><span style="font-family: Monaco; color: #333333;"><span style="font-size: 12pt;">}</span></span></div><div><br clear="none" style="font-family: Monaco; color: #333333;"/></div><div><span style="font-family: Monaco; color: #333333;"><span style="font-size: 12pt;">var  tom = new Cat(&quot;Tom&quot;);</span></span></div><div><span style="font-family: Monaco; color: #333333;"><span style="font-size: 12pt;">tom.say();</span></span></div><div><span style="font-family: Monaco; color: #333333;"><span style="font-size: 12pt;">tom.eat(&quot;apple&quot;);</span></span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">console.log(cat instanceof Animal); // true</span></div><div><span style="font-size: 12pt; font-family: Monaco; color: #333333;">console.log(cat instanceof Cat); //true</span></div></div><div><br clear="none"/></div><div><span style="font-size: 12pt; font-weight: bold;">案例：</span><span style="font-size: 12pt;">原型拖拽</span></div><div><br clear="none"/></div><div><br clear="none"/></div><div><br clear="none"/></div><div><br clear="none"/></div><div><br clear="none"/></div><div><span style="font-size: 14pt;"><br/></span></div></div><div><br/></div></span>
</div></body></html> 